﻿using System;


struct SpriteType
{
    public int x;
    public int y;
    public int speed;
    public int StartX;
    public int StartY;
    public int width;
    public int heigth;
    public bool visible;
    public Image img;
}

class Game
{
    // --------------------------------------------
    // Attributes

    const int outgame = 2000;
    const int numEnemies = 100;
    const int MAXBULLET = 100;

    static SpriteType player;
    static SpriteType[] enemy = new SpriteType[numEnemies];

    static SpriteType item;
    static SpriteType[] bullet = new SpriteType[MAXBULLET];
    

    static Font font18;

    static int score = 0;
    static int life = 3;
    static int amountBullet = 0;

    // generate random number
    static Random rnd = new Random();

    static Image brick;
    static int backgroundWidth = 32;
    static int backgroundHeight = 16;
    static int backgroundTileSize = 26;
    static string[] level1Background;

    
    static bool backIntro = false;
    // static bool finished = false;

    // --------------------------------------------
    // Methods

    static void Root()
    {
        Init();
        IntroScreen();
    }
    static void Init()
    {
        bool fullScreen = true;
        SdlHardware.Init(1024, 768, 24, fullScreen);
        font18 = new Font("data/Joystix.ttf", 18);
    }

    // Function for Start the game
    static void GameStart()
    {
        backIntro = false;
        player.img = new Image("data/player.png");
        life = 3;
        score = 0;
        amountBullet = 0;

        player.x = 50;
        player.y = 120;
        player.speed = 8;
        player.StartX = 74;
        player.StartY = 56;
        player.width = 74;
        player.heigth = 56;

        // create enemies 

        for (int i = 0; i < numEnemies; i++)
        {
            enemy[i].x = rnd.Next(200, 800);
            enemy[i].y = rnd.Next(70, 600);
            enemy[i].speed = rnd.Next(1, 20);
            enemy[i].img = new Image("data/enemy.png");
            enemy[i].width = 54;
            enemy[i].heigth = 50;
            enemy[i].visible = true;
        }

        // create item
        item.x = rnd.Next(100, 800);
        item.y = rnd.Next(70, 600);
        item.width = 40;
        item.heigth = 40;
        item.img = new Image("data/item.png");

        // create bullet
        for (int i = 0; i < MAXBULLET; i++)
        {
            bullet[i].width = 44;
            bullet[i].heigth = 22;
            bullet[i].img = new Image("data/bullet.png");
            bullet[i].speed = 20;
            bullet[i].visible = false;
        }
        

        // Game Loop
        do
        {
            // Update screen
            DrawElements();

            // Check input by the user
            CheckInput();

            // Move enemies, background, etc 
            MoveElements();

            // Check collisions and apply game logic
            CheckCollisions();

            // Pause till next frame (40 ms = 25 fps)
            WaitForNextFrame();
        }
        while (!backIntro);

        // this is for go other time to menu
        if (!backIntro)
        {
            IntroScreen();
        }

    }

    //create intro
    static void IntroScreen()
    {
        // create de background 
        brick = new Image("data/brick.png");
        level1Background = new string[] {
            "                                ",
            "                                ",
            "                                ",
            "                 XX             ",
            "                XXXX            ",
            "               XX  XX           ",
            "              XX    XX          ",
            "             XX      XX         ",
            "            XX        XX        ",
            "           XX          XX       ",
            "          XXXXXXXXXXXXXXXX      ",
            "         XX              XX     ",
            "        XX                XX    ",
            "       XX                  XX   ",
            "                                ",
            "                                ",
        };
        byte redColor = 0;
        byte greenColor = 0;
        byte blueColor = 0;
        do
        {
            SdlHardware.ClearScreen();

            for (int row = 0; row < backgroundHeight; row++)
            {
                for (int column = 0; column < backgroundWidth; column++)
                {

                    if (level1Background[row][column] == 'X')
                        SdlHardware.DrawHiddenImage(brick,
                            column * backgroundTileSize,
                            row * backgroundTileSize);
                }
            }
            SdlHardware.WriteHiddenText("press ",
                340, 440,
                redColor, greenColor, blueColor,
                font18);
            SdlHardware.WriteHiddenText("SPACE",
               420, 440,
              0x6B, 0x08, 0x08,
               font18);
            SdlHardware.WriteHiddenText("  to ENTER",
                470, 440,
                redColor, greenColor, blueColor,
                font18);

            SdlHardware.WriteHiddenText("press",
                340, 480,
               redColor, greenColor, blueColor,
                font18);
            SdlHardware.WriteHiddenText("Q",
                420, 480,
               0x6B, 0x08, 0x08,
                font18);
            SdlHardware.WriteHiddenText("  to EXIT",
                420, 480,
                redColor, greenColor, blueColor,
                font18);

            SdlHardware.ShowHiddenScreen();
            SdlHardware.Pause(30);
            redColor += 32;
            greenColor += 55;
            blueColor += 10;

            if (SdlHardware.KeyPressed(SdlHardware.KEY_SPC))
            {
                GameStart();
            }


        }
        while (!SdlHardware.KeyPressed(SdlHardware.KEY_Q));

    }

    // visible elements
    static void DrawElements()
    {
        SdlHardware.ClearScreen();

        SdlHardware.WriteHiddenText("Score: " + score,
            40, 10,
            0xCC, 0xCC, 0xCC,
            font18);
        SdlHardware.WriteHiddenText("Lifes: " + life,
            40, 40,
            0xCC, 0xCC, 0xCC,
            font18);
        SdlHardware.WriteHiddenText("bullet: " + amountBullet + "/100",
            180, 10,
            0xCC, 0xCC, 0xCC,
            font18);

        SdlHardware.DrawHiddenImage(item.img, item.x, item.y);
        for (int i = 0; i < MAXBULLET; i++)
        {
            if (bullet[i].visible)
                SdlHardware.DrawHiddenImage(bullet[i].img, bullet[i].x, bullet[i].y);
            
        }
        SdlHardware.DrawHiddenImage(player.img, player.x, player.y);
        for (int i = 0; i < numEnemies; i++)
            if(enemy[i].visible)
                SdlHardware.DrawHiddenImage(enemy[i].img, enemy[i].x, enemy[i].y);

        SdlHardware.ShowHiddenScreen();
    }

    // use keys for game
    static void CheckInput()
    {
        // block the movements for not move more than screen
        if (player.x > 0)
        {
            if (SdlHardware.KeyPressed(SdlHardware.KEY_LEFT))
                player.x -= player.speed;
        }
        if (player.x < 1024 - player.width)
        {
            if (SdlHardware.KeyPressed(SdlHardware.KEY_RIGHT))
                player.x += player.speed;
        }

        if (player.y > 70)
        {
            if (SdlHardware.KeyPressed(SdlHardware.KEY_UP))
                player.y -= player.speed;
        }
        if (player.y < 768 - player.heigth)
        {
            if (SdlHardware.KeyPressed(SdlHardware.KEY_DOWN))
                player.y += player.speed;
        }

        // add bullet
        if (SdlHardware.KeyPressed(SdlHardware.KEY_C))
        {
            if (amountBullet < MAXBULLET)
            {
                bullet[amountBullet].x = player.x;
                bullet[amountBullet].y = player.y;
                bullet[amountBullet].visible = true;
                amountBullet++;
            }
            
            // infinite bullet
            /*
            if (amountBullet > MAXBULLET-20) 
            {
                amountBullet = 0;
            }
            */
                
        }

        if (SdlHardware.KeyPressed(SdlHardware.KEY_ESC))
            backIntro = true;

    }

    // auto move for elements... items, enemies
    static void MoveElements()
    {
        for (int i = 0; i < numEnemies; i++)
        {
            enemy[i].y += enemy[i].speed;
            if ((enemy[i].y < 70) || (enemy[i].y > 768 - enemy[i].heigth))
                enemy[i].speed = -enemy[i].speed;
            if (!enemy[i].visible)
                enemy[i].speed = 0;
        }
        for (int i = 0; i < MAXBULLET; i++)
        {
            if (bullet[i].visible)
            {
                bullet[i].x += bullet[i].speed;
            }
        }
        
        
    }

    // collisions 
    static void CheckCollisions()
    {
        // collision for enemies
        for (int i = 0; i < numEnemies; i++)
        {

            if ((player.x < enemy[i].x + enemy[i].width) &&
                (player.x + player.width > enemy[i].x) &&
                (player.y < enemy[i].y + enemy[i].heigth) &&
                (player.y + player.heigth > enemy[i].y)
                    )
            {
                life--;
                player.x = player.StartX;
                player.y = player.StartY;
            }

            for (int j = 0; j < MAXBULLET; j++)
            {
                if ((bullet[j].x < enemy[i].x + enemy[i].width) &&
                (bullet[j].x + bullet[j].width > enemy[i].x) &&
                (bullet[j].y < enemy[i].y + enemy[i].heigth) &&
                (bullet[j].y + bullet[j].heigth > enemy[i].y)
                    )
                {
                    enemy[i].visible = false;
                    bullet[j].visible = false;
                    enemy[i].x = outgame;
                    bullet[j].x = outgame;
                }
            }
        }
        
        //collision for items

        if ((player.x < item.x + item.width) &&
            (player.x + player.width > item.x) &&
            (player.y < item.y + item.heigth) &&
            (player.y + player.heigth > item.y)
                )
        {
            score += 10;
            item.x = rnd.Next(100, 800);
            item.x = rnd.Next(70, 800);
        }
        if (score > 20)
        {
            Root();
        }
        if (life == 0)
        {
            Root();
        }
    }

    static void WaitForNextFrame()
    {
        SdlHardware.Pause(40);
    }


    // --------------------------------------------
    // Body
    static void Main(string[] args)
    {
        Root();


    }
}